import commands
import os
from sqliteDB import sqliteDB
from pimParser import vcard_tags,ics_tags
##@author Alessio Di Pietro
#@author Irene Scionti
#@brief allows to find an entry
class pimFinder(object):
    '''
    Execute pim search returning entry uid and revision number
    '''

    ##@param settings settings object
    def __init__(self,settings):
        '''
        Constructor
        '''
        self.__settings=settings
        #svn parameters
        self.__entry_paths=[settings.contacts_diffname,settings.calendar_diffname,settings.memos_diffname];
        self.__svnworkingcopy=settings.svnWorkingCopy
        self.__svnserver=settings.svnServer;
        
        #database parameters
        self.__fts_db_name=settings.fts_db;
        self.__fts_db=sqliteDB(self.__svnworkingcopy+'/index/'+self.__fts_db_name)
        print self.__svnworkingcopy+'/index/'+self.__fts_db_name
        self.__fts_table_names=["contacts_index","calendar_index","memos_index"]
        
    ## @brief avoids hidden files or directory in ls command
    def __nodot(self,item): 
        return item[0] != '.'
    ## @brief full tect search
    # @param entry_type entry type (contact,calendar,memos)
    # @oaram tag tag of search field (defined in pimParser.ics_tags and pimParser.vcard_tags)
    # @return a list of founded entries (uid,rev,body,state,timestamp,removed_timestamp)
    def fts(self,key,entry_type,tag):
        '''
        execute full text entry search
        '''
        print "searching..."
        c=self.__fts_db.open();
        #regular expression for finding 
        # search key* near (1 char) the tag
        regex=tag+" NEAR/1 "+key+'*';
        c.execute("SELECT uid,rev,body,state,timestamp,removed_timestamp FROM "+self.__fts_table_names[entry_type]+" WHERE body MATCH ?",(regex,))
        found=c.fetchall();
        self.__fts_db.close();
        print "found",found
        return found

    ## @brief sequential search
    # @param entry_type entry type (contact,calendar,memos)
    # @oaram tag tag of search field (defined in pimParser.ics_tags and pimParser.vcard_tags)
    # @return a list of founded entries (uid,rev,body,"","","")
    def seq_search(self,key,entry_type,tag):
        '''
        execute sequential search on non-indexed entries
        '''
        print "\nsearching..."
        c=self.__fts_db.open();
        #execute seq_search only on not indexed revisions
        c.execute("SELECT uid,min(rev) FROM "+self.__fts_table_names[entry_type]+" GROUP BY uid HAVING cutted='true'");
        found=[]
        regex=tag+key+"*"
        for row in c:
            entry_url="svn://"+self.__svnserver+self.__entry_paths[entry_type]+'/'+row[0]+'/'+row[0];
            #execute svn log command to retrieve not indexed entry revision
            svnlog=commands.getoutput("svn log "+entry_url+'@'+str(int(row[1])-1)+" 2> /dev/null | grep ^r[0-9] | awk '{print substr($1,2,9)}'")
            not_indexed_revisions=svnlog.split("\n")
            #for each of theese revisions
            for rev in not_indexed_revisions:
                #if svn cat is not empty -> found a revision
                svncat=commands.getoutput("svn cat "+entry_url+'@'+rev+" | grep "+regex)
                if svncat!="":
                    found.append((row[0],rev,svncat,'','','null'))
        self.__fts_db.close();
        return found
    ## @brief find (seq+ind)
    # return founded entries
    def find(self, key, entry_type,tag):
        indexed_found=self.fts(key, entry_type,tag)
        not_indexed_found=self.seq_search(key, entry_type,tag)
        return indexed_found+not_indexed_found


    
    